#include <iostream>
#include <cstdlib>
#include <string>

#include "configuration.h"

using namespace jolfs;

void print_conf_nodes( const Configuration& conf )
{
  std::cout << "NODES" << std::endl;
  const Configuration::NodeList& list = conf.getNodes();
  Configuration::NodeList::const_iterator it = list.begin();
  for (; it!=list.end(); ++it )
  {
    std::cout << "  Node" << std::endl;
    std::cout << "    source: " << (*it)->getSource() << std::endl;
    std::string t;
    switch ( (*it)->getType() )
    {
      case Configuration::Node::LOCAL:
        t = "LOCAL";
        break;
      case Configuration::Node::REMOTE:
        t = "REMOTE";
        break;
      default:
        t = "?";
        break;
    }
    std::cout << "    type:   " << t << std::endl;
  }
}

void print_indent( unsigned int indent )
{
  for ( unsigned int i=0; i<indent; ++i )
    std::cout << "  ";
}

void print_node( const Configuration::Node* node )
{
  std::string t;
  switch ( node->getType() )
  {
    case Configuration::Node::LOCAL:
      t = "LOCAL";
      break;
    case Configuration::Node::REMOTE:
      t = "REMOTE";
      break;
    default:
      t = "?";
      break;
  }
  std::cout << t << ":" << node->getSource();
}

void print_volume( const Configuration::Volume* volume, unsigned int indent, const std::string& name="" )
{
  std::string l;
  switch ( volume->getLink() )
  {
    case Configuration::Volume::MERGE:
      l = "MERGE";
      break;
    case Configuration::Volume::REPLICATE:
      l = "REPLICATE";
      break;
    default:
      l = "?";
      break;
  }
  print_indent(indent);
  std::cout << volume->getName() << "/ (" << l;
  if ( volume->getNode()!=0 )
  {
    std::cout << " ";
    print_node(volume->getNode());
  }
  std::cout << ")" << std::endl;
  const Configuration::Volume::VolumeList& volumes = volume->getVolumes();
  Configuration::Volume::VolumeList::const_iterator it = volumes.begin();
  for (; it!=volumes.end(); ++it )
    print_volume( *it, indent+1 );
}

void print_conf_volumes( const Configuration& conf )
{
  std::cout << "VOLUMES" << std::endl;
  print_volume( &conf.getMountVolume(), 1, "/" );
}

int main( int argc, char** argv )
{
  Configuration configuration;
  
  // Configuring nodes
  Configuration::Node node1( Configuration::Node::LOCAL, "/tmp/jolfs/a/" );
  Configuration::Node node2( Configuration::Node::LOCAL, "/tmp/jolfs/b/" );
  Configuration::Node node3( Configuration::Node::LOCAL, "/tmp/jolfs/c/" );
  Configuration::Node node4( Configuration::Node::LOCAL, "/tmp/jolfs/d/" );
  
  configuration.addNode( &node1 );
  configuration.addNode( &node2 );
  configuration.addNode( &node3 );
  configuration.addNode( &node4 );
  
  print_conf_nodes( configuration );
 
  // Configuring volumes
  Configuration::Volume volume1( "a", Configuration::Volume::MERGE, &node1 );
  Configuration::Volume volume2( "b", Configuration::Volume::MERGE, &node2 );
  Configuration::Volume volume3( "c", Configuration::Volume::MERGE, &node3 );
  Configuration::Volume volume4( "d", Configuration::Volume::MERGE, &node4 );
  
  Configuration::Volume& mountVolume = configuration.getMountVolume();
  mountVolume.addVolume( &volume1 );
  mountVolume.addVolume( &volume2 );
  volume2.addVolume( &volume3 );
  volume3.addVolume( &volume4 );
  
  print_conf_volumes( configuration );
  
  return EXIT_SUCCESS;
}